package com.ficus.road.maintain.handler.monitor;

import com.ficus.road.maintain.core.model.AlertTypeEnum;
import com.ficus.road.maintain.dao.OperationLogDao;
import com.ficus.road.maintain.dto.*;
import com.ficus.road.maintain.util.FormatUtil;
import com.ficus.road.maintain.util.MyDateUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.core.annotation.Order;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author xiawen yang
 * @date 2022/5/23 下午7:18
 */
@Order(4)
@Component
@Slf4j
@RequiredArgsConstructor
public class StatisticMonitorHandler extends AbstractMonitorHandler {

    private final OperationLogDao operationLogDao;

    @Override
    Checklist doFilter(Checklist fetch) {
        log.info("推送统计开始");
        long start = System.currentTimeMillis();
        Date date = new Date();
        String yesterdayDateStr = MyDateUtil.dateFormatStr(DateUtils.addDays(date, -1), "yyyy-MM-dd");
        List<ChecklistOfCar> carCheckList = fetch.getCarList();
        PushStatistic pushStatistic = fetch.getPushStatistic();

        //异常统计
        double carOutNum = 0, carErrorNum = 0;
        List<CarAlertInfo> carAlertInfoList = new ArrayList<>();
        int carStatusError = 0, gnssError = 0, lidarError = 0, cameraError = 0, storageError = 0;
        for (int i = 0; i < carCheckList.size(); i++) {
            boolean isError = false;
            ChecklistOfCar checklistOfCar = carCheckList.get(i);
            if (checklistOfCar.getIsCarOutStatusError().equals(1)) {
                isError = true;
                carStatusError++;
                CarAlertInfo carAlertInfo = CarAlertInfo.builder().carId(checklistOfCar.getCarId())
                        .alertType(AlertTypeEnum.CarOutStatusError.getKey()).alertData("1").build();
                carAlertInfoList.add(carAlertInfo);
            }
            if (checklistOfCar.getIsGNSSError().equals(1)) {
                isError = true;
                gnssError++;
                CarAlertInfo carAlertInfo = CarAlertInfo.builder().carId(checklistOfCar.getCarId())
                        .alertType(AlertTypeEnum.GNSSError.getKey()).alertData(String.valueOf(checklistOfCar.getGNSSErrorTimes())).build();
                carAlertInfoList.add(carAlertInfo);
            }
            if (checklistOfCar.getIsLidarError().equals(1)) {
                isError = true;
                lidarError++;
                CarAlertInfo carAlertInfo = CarAlertInfo.builder().carId(checklistOfCar.getCarId())
                        .alertType(AlertTypeEnum.LidarError.getKey()).alertData(String.valueOf(checklistOfCar.getLidarErrorTimes())).build();
                carAlertInfoList.add(carAlertInfo);
            }
            if (checklistOfCar.getIsCameraError().equals(1)) {
                isError = true;
                cameraError++;
                CarAlertInfo carAlertInfo = CarAlertInfo.builder().carId(checklistOfCar.getCarId())
                        .alertType(AlertTypeEnum.CameraError.getKey()).alertData(String.valueOf(checklistOfCar.getCameraErrorTimes())).build();
                carAlertInfoList.add(carAlertInfo);
            }
            if (checklistOfCar.getStorageDiskCap() < 500) {
                isError = true;
                storageError++;
                CarAlertInfo carAlertInfo = CarAlertInfo.builder().carId(checklistOfCar.getCarId())
                        .alertType(AlertTypeEnum.CarStorageDiskLow.getKey()).alertData(String.valueOf(checklistOfCar.getStorageDiskCap())).build();
                carAlertInfoList.add(carAlertInfo);
            }
            if (checklistOfCar.getCloudCarStatus().equals(1)) {
                carOutNum++;
            }
            if (isError) {
                carErrorNum++;
            }
        }
        CarStatistic carStatistic = CarStatistic.builder().carOutNum(carOutNum).carErrorNum(carErrorNum).build();
        //异常统计
        fetch.setCarStatistic(carStatistic);
        //异常告警
        fetch.setCarAlertInfoList(carAlertInfoList);
        //异常分布
        AlertDistribute alertDistribute = AlertDistribute.builder().carStatusError(carStatusError).gnssError(gnssError)
                .lidarError(lidarError).cameraError(cameraError).storageDiskError(storageError).build();
        fetch.setAlertDistribute(alertDistribute);
        //推送统计
        double push2ThirdPartyTotal = operationLogDao.count(new Query(Criteria.where("title").is("推送中海").and("operate_date").gte(MyDateUtil.getStartOfDay(new Date()))));
        double push2ThirdPartySuccess = operationLogDao.count(new Query(Criteria.where("title").is("推送中海").and("type").is("info").and("operate_date").gte(MyDateUtil.getStartOfDay(new Date()))));
        double successRate1 = push2ThirdPartyTotal == 0 ? 0 : FormatUtil.keepDecimalsOfK(push2ThirdPartySuccess / push2ThirdPartyTotal, 2);
        double push2YtTotal = operationLogDao.count(new Query(Criteria.where("title").is("中海回调").and("operate_date").gte(MyDateUtil.getStartOfDay(new Date()))));
        double push2YtSuccess = operationLogDao.count(new Query(Criteria.where("title").is("中海回调").and("type").is("info").and("operate_date").gte(MyDateUtil.getStartOfDay(new Date()))));
        double successRate2 = push2YtTotal == 0 ? 0 : FormatUtil.keepDecimalsOfK(push2YtSuccess / push2YtTotal, 2);
        pushStatistic.setPush2ThirdPartyFail((int) (push2ThirdPartyTotal - push2ThirdPartySuccess));
        pushStatistic.setPush2ThirdPartySuccess((int) push2ThirdPartySuccess);
        pushStatistic.setPush2ThirdPartySuccessRate(successRate1);
        pushStatistic.setPush2YtFail((int) (push2YtTotal - push2YtSuccess));
        pushStatistic.setPush2YtSuccess((int) push2YtSuccess);
        pushStatistic.setPush2YtSuccessRate(successRate2);

        checklistDao.saveOrUpdate(fetch);
        log.info("推送统计耗时： {} ms", System.currentTimeMillis() - start);
        return fetch;
    }
}
